﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Extensil.Common;
using Extensil.Processor;
using System.Reflection;
using System.Configuration;
using Extensil.Common.CategoryHandler;
using Extensil.Category;
using Extensil.Common.CategoryHandler.Discovery;
using Extensil.Category.Discovery;
using Extensil.HotKeys;
using Extensil.Helper;
using System.IO;

namespace Extensil
{
    public partial class ExtensilManager :UserForm, ISuperForm
    {
        static Dictionary<string, RightPane> _formCache;
        static Dictionary<Keys, ComboPropertyParam> _hotKeyWindow = new Dictionary<Keys, ComboPropertyParam>();
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);

            if(m.Msg == WindowsShell.WM_HOTKEY)
            {
                int keyData = HotKeyManager.GetHotKeys((int)m.LParam);
                if(_hotKeyWindow.ContainsKey((Keys)keyData))
                    OpenCategoryForm(_hotKeyWindow[(Keys)keyData]);
            }
        }
        public ExtensilManager()
        {
            InitializeComponent();
            _formCache = new Dictionary<string, RightPane>();
            tvCategory.AfterSelect += new TreeViewEventHandler(tvCategory_AfterSelect);
            tvCategory.NodeMouseClick += new TreeNodeMouseClickEventHandler(tvCategory_NodeMouseClick);
            Reload();
        }
        protected override void OnLoad(EventArgs e)
        {
            RunFirstTimeEvent();
            this.Close();
        }
        private void RunFirstTimeEvent()
        {
            if(CategorySection.GetConfig().IsFirstTime)
            {
                AutoStart.Current.EnabledThroughStartupMenu = true;
                using(ConfigModifier cm = new ConfigModifier())
                {
                    cm.ToggleFirstTime();
                }
            }
        }

        void tvCategory_AfterSelect(object sender, TreeViewEventArgs e)
        {
            LoadRightPane((ComboPropertyParam)e.Node.Tag);
        }
        void tvCategory_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if(e.Button == MouseButtons.Right)
            {
                contextMenuStrip2.Tag = e.Node.Tag;
                contextMenuStrip2.Show(e.X, e.Y);
            }
        }
        void LoadRightPane(ComboPropertyParam param)
        {
            RightPane rPane;
            try
            {
                rPane = GetSetRightPane(param.Key);
            }
            catch(Exception exc)
            {
                throw new Exception("Could not load category form " + param.Key + ". " + exc.Message, exc.InnerException);
            }
            if(rPane != null)
            {
                rPane.Show();
                splitContainer2.Panel2.Controls.Clear();
                splitContainer2.Panel2.Controls.Add(rPane);
            }
        }
        public void ReportStatus(int progress, string message)
        {
            lblStatus.Text = message;
            bool log=false;
            string allowLogging = ConfigurationManager.AppSettings["AllowLogging"];
            if(!String.IsNullOrEmpty(allowLogging) && bool.TryParse(allowLogging, out log) && log)
                File.AppendAllText("extensil.log", "\r\n" + DateTime.Now.ToShortTimeString() + " - " + message);
        }
        public void Reload()
        {
            try
            {
                string currentScreen = null;
                if(tvCategory.SelectedNode != null)
                    currentScreen = ((ComboPropertyParam)tvCategory.SelectedNode.Tag).Key;
                CategoryFactory.Reset();
                LoadCategories();

                // Load Auto Starts and set hotkeys
                List<ComboPropertyParam> ds = CategoryFactory.GetAllCategories();
                foreach(ComboPropertyParam param in ds)
                {
                    if(param.AutoStart)
                    {
                        try
                        {
                            GetSetRightPane(param.Value);
                        }
                        catch(Exception exc)
                        {
                            throw new Exception("Could not load category form " + param.Key + ". " + exc.Message);
                        }
                    }
                    if(!String.IsNullOrEmpty(param.HotKey))
                    {
                        Keys keys = HotKeyManager.Parse(param.HotKey);
                        WindowsShell.RegisterHotKey(this, keys);
                        if(!_hotKeyWindow.ContainsKey(keys))
                            _hotKeyWindow.Add(keys, param);
                    }
                }

                // Reselect currentScreen
                if(currentScreen != null && tvCategory.Nodes[currentScreen] != null)
                    tvCategory.SelectedNode = tvCategory.Nodes[currentScreen];
                else if(tvCategory.Nodes.Count > 0)
                    tvCategory.SelectedNode = tvCategory.Nodes[0];

                LoadRightPane((ComboPropertyParam)tvCategory.SelectedNode.Tag);
            }
            catch(Exception exc)
            {
                AlertBox.ShowDialog("Error while loading category form. ", exc);
            }
        }
        void LoadCategories()
        {
            List<ComboPropertyParam> ds = CategoryFactory.GetAllVisibleCategories();

            tvCategory.Nodes.Clear();
            foreach(ComboPropertyParam param in ds)
            {
                TreeNode tn = tvCategory.Nodes.Add(param.Key, param.Key);
                tn.Tag = param;
            }
        }
        RightPane GetSetRightPane(string name)
        {
            RightPane rPane = null;
            
            if(_formCache.ContainsKey(name))
                rPane = _formCache[name];
            else
            {
                rPane = new RightPane(name);
                _formCache.Add(name, rPane);
            }
            if(rPane != null)
            {
                rPane.TopLevel = false;
                rPane.Dock = DockStyle.Fill;
                rPane.FormBorderStyle = FormBorderStyle.None;
                rPane.ContainerForm = (UserForm)this;
            }
            return rPane;
        }

        private void TaskManager_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(!_forceClose)
            {
                MinimizeForm();
                e.Cancel = true;
            }
            else
            {
                WindowsShell.UnregisterHotKey(this);
            }
        }
        void MinimizeForm()
        {
            this.Hide();
            WindowState = FormWindowState.Minimized;
        }
        void MaximizeForm()
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }
        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            MaximizeForm();
        }

        private void TaskManager_Resize(object sender, EventArgs e)
        {
            if(WindowState == FormWindowState.Minimized)
            {
                MinimizeForm();
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MaximizeForm();
        }
        bool _forceClose = false;
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _forceClose = true;
            this.Close();
        }

        private void openInNewWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenCategoryForm((ComboPropertyParam)contextMenuStrip2.Tag);
        }
        void OpenCategoryForm(ComboPropertyParam param)
        {
            RightPane rPane = rPane = new RightPane(param.Key);
            rPane.Text = param.Key;
            rPane.Show();
            rPane.WindowState = FormWindowState.Maximized;
            rPane.Focus();
        }
    }
}
